package com.foreknow.reflection;

import java.awt.*;
import java.lang.reflect.Method;
import java.util.Hashtable;

/**
 * java反射机制是Java语言中的一个非常重要的特性,它有动态机制-----反射
 * 反射的特点:
 * 1.在程序运行的时候会判断任意一个对象所属的类
 * 2.在运行的时候获取类的对象
 * 3.运行的时候获取到类所具有的成员变量和方法
 *
 * 总结:通过运行结果可以发现，Java的反射机制使得在运行时能够判断一个对象所属的类，获取对象的方法并进行调用，并获取方法的返回结果。
 * 实例化Class类对象有以下几种方式
 * 1.前提:已知是一个具体的类,大家可以通过class属性来获取,这种方法是最安全的,并且性能高
 * Class clazz=String.class; Mybatis中获取类对象:UserMapper.class
 */
public class ReflectionDemo {
   public void getNameTest() throws ClassNotFoundException {
       String name="这是一个反射测试";
       Class aClass = name.getClass();
       System.out.println("String的类名"+aClass.getName());
       Button btn=new Button();
       Class btnClass = btn.getClass();
       System.out.println("Button类名:"+btnClass.getName());
      Class superBtnClass= btnClass.getSuperclass();
       System.out.println("Button的父类名"+superBtnClass.getName());
       Class clsTest=Class.forName("java.awt.Button");
       System.out.println("clsTest name"+clsTest.getName());


   }

    /**
     * 此方法可以通过反射机制去调用testMesthod方法,而无需手动调用
     * @throws Exception
     */
    public void getMethodTest()throws Exception{
        Class cls = Class.forName("com.foreknow.reflection.ReflectionDemo");
        Class ptypes[]=new Class[2];
        ptypes[0]=Class.forName("java.lang.String");
        ptypes[1]=Class.forName("java.util.Hashtable");
        //此方法是获取到我们想要调用的方法的名称(methodName)以及参数的类型(parameterType)
        Method method = cls.getMethod("testMesthod", ptypes);
        Object[] args=new Object[2];
        args[0]="hello tom";
        Hashtable<String,String> ht=new Hashtable<String, String>();
        ht.put("name","你好这是一个map");
        args[1]=ht;
        //我们需要调用testMethod这个方法
       String returnStr=(String) method.invoke(new ReflectionDemo(),args);
        System.out.println("return="+returnStr);
    }
    public String testMesthod(String str, Hashtable ht)throws Exception{
       String returnStr="这是方法的返回值";
        System.out.println("测试testMethod()方法调用");
        System.out.println("str="+str);
        System.out.println("名字="+(String) ht.get("name"));
        System.out.println("结束了testMethod()方法的调用");
       return returnStr;
    }
    public static void main(String[] args) throws Exception {
        ReflectionDemo reflectionDemo=new ReflectionDemo();
        reflectionDemo.getMethodTest();
    }
}
